﻿/*
Copyright (c) 2010 Vratislav Cermak (vratacermak@gmail.com)
 
This file is part of TeachMe Project. See http://code.google.com/p/teach-me for more information.
 
TeachMe is an open source project. Using of TeachMe is free of charge.
It is distributed under GNU General Public License version 3 (GPLv3).
GPLv3 can be found at http://www.gnu.org/licenses/gpl.html.
 
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the license for more details.
*/

using System;
using System.IO;
using System.Net;
using System.Threading;
using TeachMe.Application.Forms;
using TeachMe.Application.Properties;

namespace TeachMe.Application
{
    public class OnlineVersionChecker
    {
        private class VersionCheckerThreadWorkerData : ThreadWorkerData
        {
            public Root Root { get; set; }
            public bool Silent { get; set; }
        }

        private static void ThreadWorker(object obj)
        {
            VersionCheckerThreadWorkerData worker = obj as VersionCheckerThreadWorkerData;
            if (worker == null)
            {
                throw new InvalidOperationException();
            }

            OnlineVersion onlineVersion = null;

            using (WebClient client = new WebClient())
            {
                // TODO: add .net version(s) to user agent

                string userAgent = String.Format("TeachMe/{0} ({1}; {2}; {3})", worker.Root.CurrentVersion, Environment.OSVersion.VersionString, Environment.OSVersion.Platform, worker.Root.UserSettings.Language.Value);
                string link = String.Format("http://www.teachme.cz/version.php?id={0}", worker.Root.UserSettings.Id.Value);

                client.Headers.Add("user-agent", userAgent);

                try
                {
                    Logging.Debug(typeof(OnlineVersion), "Checking new version with: {0}", link);

                    worker.UpdateStatus(Resources.ConnectingToServer);

                    // TODO: timeout

                    using (Stream data = client.OpenRead(link))
                    {
                        worker.UpdateStatus(Resources.ParsingResponse);

                        if (!worker.Canceled)
                        {
                            using (StreamReader reader = new StreamReader(data))
                            {
                                onlineVersion = OnlineVersion.Load(reader.ReadToEnd());
                            }
                        }
                    }
                }
                catch (WebException e)
                {
                    Logging.Error(typeof(OnlineVersion), e, "Could check new version availability.");
                }
            }

            worker.Exit();

            if (onlineVersion != null)
            {
                worker.Root.DisplayOnlineVersionInfo(onlineVersion, worker.Silent);
            }
        }
        
        /// <summary>
        /// Checks for new version.
        /// </summary>
        /// <param name="root"></param>
        /// <param name="silent">Silent mode is used for automated check and we do not display busy form.</param>
        public static void Check(Root root, bool silent)
        {
            VersionCheckerThreadWorkerData worker = new VersionCheckerThreadWorkerData { Root = root, Silent = silent};

            if (!silent)
            {
                BusyForm form = new BusyForm(worker) { WaitCaption = Resources.CheckingForNewVersion };

                form.Center();
                form.Show();
            }

            Thread thread = new Thread(ThreadWorker) { CurrentUICulture = Thread.CurrentThread.CurrentUICulture };
            thread.Start(worker);
        }
    }
}
